home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SHUFFL11.ZIP / SHUFFLE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-12  |  28.4 KB  |  643 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <conio.h>
  4. #include <ctype.h>
  5. #include <dpmi.h>
  6. #include <go32.h>
  7. #include <pc.h>
  8. #include <math.h>
  9. #include <sys\farptr.h>
  10. #include "sb_lib.h"
  11. #include "sbdetect.h"
  12. #include "sb_misc.h"
  13. #include "allegro.h"       /* Allegro game programming library header file */
  14. #include "shuffle.h"             /* Contains information about SHUFFLE.DAT */ 
  15. typedef struct                     /* Contains information for each player */
  16. {
  17.    int old_x, old_y, x, y, speed_x, speed_y, score, device;
  18.    BITMAP *bat, *progress;
  19. }  player;
  20. void mixingDemo(void);
  21. void modDemo(void);
  22. sb_sample *sample[2];
  23. sb_mod_file *mod;
  24. sb_status stat;
  25. player one, two, ball;
  26. long frame_count = 10;                     /* Incremented by 1 every cycle */
  27. volatile int game_time = 1;               /* Incremented by 1 every second */
  28. FILE *fp;                         /* File pointer used only in debug mode  */
  29. int goal_dist = 30;                  /* Half distance goal posts are apart */
  30. int exit_loop = 0;                           /* Used for exiting main loop */
  31. int debug = 0;                               /* Used to control debug mode */
  32. int game_speed = 10;                       /* Speed at which the game goes */
  33. int sound_on = 1;                                 /* Used to control sound */
  34. int t = 0;                            /* Used for fade in routine at start */
  35. int show_frame = 1;                  /* Used to control frequency of draws */
  36. int redo = 0;                               /* Used to control spin effect */
  37. int score_max = 11;                     /* Represents score to play to - 1 */
  38. char score_buf[80], c;            /* Used to show fps & also in debug mode */
  39. double const pi = 3.14159265;       /* Used for angles (angles are in rad) */
  40. int just_hit = 0;                    /* Used to help prevent repeated hits */
  41. double fps = 20;                 /* Used to calc the fps rate & control speed */
  42. BITMAP *active_page, *page1, *page2, *page3; /* Current & sub page bitmaps */
  43. BITMAP *end1, *end2, *shrink, *rotate;                     /* Misc bitmaps */
  44. DATAFILE *datafile;                            /* Used to read shuffle.dat */
  45. void game_timer()               /* This function increments game_time by 1 */
  46. {                               /* and is called every 1000ms (1 second)   */
  47.    game_time++;                 /* so that the fps rate can be calculated  */
  48. }
  49. END_OF_FUNCTION(game_timer);
  50. double too_circle(double x, double y)     /* Used by ball_interaction to   */
  51. {                                         /* calculate whole circle angles */
  52.    double temp_angle;
  53.    if(y != 0) temp_angle = atan(x/y);
  54.       else if(x < 0) return(3*pi/2);
  55.          else return(pi);
  56.    if(y > 0) return(pi - temp_angle);
  57.    if(x > 0) return(   0 - temp_angle);
  58.    if(x < 0) return(pi*2 - temp_angle);
  59.    return(temp_angle);
  60. }
  61. void main(int argc, char *argv[])
  62. {
  63.    int too_close = 0;             /* Postive if ball is too close to a bat */
  64.    int x, y, w = 0, an_pos = 0, an_dir = 1;
  65.    int word = 0;                  /* Stores which word should be displayed */
  66.    int human_speed, computer_speed;       /* Variables storing max. speeds */
  67.    int show_const = 2;            /* Controls how often the graphics drawn */
  68.    int serve = 0;                /* 0 - Player 1 serve, 1 - Player 2 serve */
  69.    int boris = 0;           /* Helps calculate when the word should change */
  70.    int smiley = 0;              /* Controls whether smiley face is showing */
  71.    int eofscore;
  72.    char *message[] =            /* Contains message shown during game play */
  73.    {
  74.       "this","game","is","coming","to","you","all","the","way","from","nz",
  75.       "i","made","it","to","try","out","djgpp","with","the","allegro",
  76.       "library","thanx","to","the","dudes","who","made","them","hope","you",
  77.       "enjoy","playing","this","anyone","with","some","better","routine",
  78.       "for","making","the","balls","bounce","right","is","welcome","to",
  79.       "donate","it","to","me","my","email","address","is","michael","dot",
  80.       "bevin","at","stone","bow","dot","otago","dot","ac","dot","nz","",
  81.       "god","bless","you","all","","james","4;8","draw","near","to","god",
  82.       "and","he","will","draw","near","to","you","","that","verse","came",
  83.       "to","you","from","the","bible","which","is","the","word","of","god",
  84.       "amen","",NULL
  85.    };
  86.    for(x=1;x<argc;x++) {
  87.    if(!strcmp(argv[x], "-1")) show_const = 1;
  88.    if(!strcmp(argv[x], "-2")) show_const = 3;
  89.    if(!strcmp(argv[x], "-3")) show_const = 4;
  90.    if(!strcmp(argv[x], "-n")) sound_on = 0;
  91.    if(!strcmp(argv[x], "-d")) {debug = 1;fp=fopen("data.dat","wb");}
  92.    if(!strcmp(argv[x], "-s1")) game_speed = 5;
  93.    if(!strcmp(argv[x], "-s2")) game_speed = 15;
  94.    if(!strcmp(argv[x], "-s3")) game_speed = 20;
  95.    }
  96.    init();
  97.    install_int(game_timer, 1000);
  98.    intro();
  99. restart:
  100.    frame_count *= (2.3 * show_const);
  101.    if(two.device < 3) serve = 1;
  102.    if(one.device < 3) serve = 0;
  103.    if((two.device < 3 && one.device < 3) || (two.device > 2 && one.device > 2)) serve = rand() % 2;
  104.    if(!serve) {ball.x=16000; ball.y=14000;}
  105.    if(serve) {ball.x=16000; ball.y=6000;} 
  106.    if(smiley) draw_compiled_sprite(page3, datafile[BITMAP_007].dat, 0, 0);
  107.    else draw_compiled_sprite(page3, datafile[BITMAP_002].dat, 0, 0);
  108.    while(!key[KEY_ESC] && !exit_loop)
  109.    {
  110.       human_speed=1000*fps; frame_count++; show_frame--;
  111.       if(just_hit) just_hit--;
  112.       w--; if(w < 0) w = 0;
  113.       if((ball.y+ball.speed_y) >= 16900) {
  114.         if((ball.speed_x*(16900-ball.y))/ball.speed_y+ball.x > 16000-goal_dist*100 
  115.         && (ball.speed_x*(16900-ball.y))/ball.speed_y+ball.x < 16000+goal_dist*100 ) {
  116.            if(sound_on) sb_mix_sample(sample[1]);
  117.            if (serve==1) two.score++;
  118.               else serve=1;
  119.            if(two.score == score_max+1) {exit_loop = 2; two.score = 0;}
  120.            else {
  121.               ball.x=16000; ball.y=6000;
  122.               ball.speed_x=0; ball.speed_y=0;
  123.               one.x = 16000; one.y = 16900; two.speed_x = 0; two.speed_y = 0; 
  124.               two.x = 16000; two.y = 3000; one.speed_x = 0; one.speed_y = 0;
  125.            }
  126.         }
  127.         else {
  128.            ball.speed_y *= -0.95;
  129.            if(sound_on) {
  130.               sample[0]->left_volume=20;
  131.               sample[0]->right_volume=20;
  132.               sb_mix_sample(sample[0]);
  133.            }
  134.         }
  135.       }
  136.       if ((ball.y+ball.speed_y) <= 3000) {
  137.         if((ball.speed_x*(3000-ball.y))/ball.speed_y+ball.x > 16000-goal_dist*100 
  138.         && (ball.speed_x*(3000-ball.y))/ball.speed_y+ball.x < 16000+goal_dist*100 ) {
  139.            if(sound_on) sb_mix_sample(sample[1]);
  140.            if (serve==0) one.score++;
  141.               else serve=0;
  142.            if(one.score == score_max+1) {exit_loop = 1; one.score = score_max;}
  143.            else {
  144.               ball.x=16000; ball.y=14000;
  145.               ball.speed_x=0; ball.speed_y=0;
  146.               one.x = 16000; one.y = 16900; two.speed_x = 0; two.speed_y = 0; 
  147.               two.x = 16000; two.y = 3000; one.speed_x = 0; one.speed_y = 0;
  148.            }
  149.         }
  150.         else {
  151.            ball.speed_y *= -0.95;
  152.            if(sound_on) {
  153.               sample[0]->left_volume=20;
  154.               sample[0]->right_volume=20;
  155.               sb_mix_sample(sample[0]);
  156.            }
  157.         }
  158.       }
  159.       if((ball.x+ball.speed_x) >= 22900 || (ball.x+ball.speed_x) <= 9000) {
  160.          ball.speed_x*=-0.95;
  161.          if(sound_on) {
  162.             sample[0]->left_volume=20;
  163.             sample[0]->right_volume=20;
  164.             sb_mix_sample(sample[0]);
  165.          }
  166.      }
  167.       ball.x += ball.speed_x; ball.y += ball.speed_y;
  168.       switch(one.device)
  169.       {
  170.          case 0 :
  171.             one.speed_x+=(mouse_x-100)*4*(game_speed/fps)*(game_speed/fps)*show_const;
  172.             one.speed_y+=(mouse_y-100)*4*(game_speed/fps)*(game_speed/fps)*show_const;
  173.             if(one.speed_x > human_speed) one.speed_x = human_speed;
  174.             else if(one.speed_x < -human_speed) one.speed_x = -human_speed;
  175.             if(one.speed_y > human_speed) one.speed_y = human_speed;
  176.             else if(one.speed_y < -human_speed) one.speed_y = -human_speed;
  177.             break;
  178.          case 1 :
  179.             if(key[KEY_UP])    one.speed_y = -human_speed;
  180.             if(key[KEY_DOWN])  one.speed_y = human_speed;
  181.             if(key[KEY_RIGHT]) one.speed_x = human_speed;
  182.             if(key[KEY_LEFT])  one.speed_x = -human_speed;
  183.             break;
  184.          case 2 :
  185.             if(key[KEY_W]) one.speed_y = -human_speed;
  186.             if(key[KEY_X] || key[KEY_S]) one.speed_y = human_speed;
  187.             if(key[KEY_D]) one.speed_x = human_speed;
  188.             if(key[KEY_A]) one.speed_x = -human_speed;
  189.             break;
  190.          case 3 :  computer_speed=150*fps;
  191.             break;
  192.          case 4 :  computer_speed=300*fps;
  193.             break;
  194.          case 5 :  computer_speed=450*fps;
  195.             break;
  196.          default : computer_speed=700*fps;
  197.       }
  198.       if(one.device > 2) {
  199.          if(one.x > ball.x && one.x > 9000) one.speed_x = -computer_speed;
  200.          if(one.x < ball.x && one.x < 22900) one.speed_x = computer_speed;
  201.          if(one.y > ball.y && ball.y > 10000) one.speed_y = -computer_speed;
  202.          if(one.y < 16900 && (ball.y < 10000 || one.y < ball.y+1000)) one.speed_y = computer_speed;
  203.          if(abs(one.x-ball.x) < 500 && ball.y < 10000) one.speed_x=computer_speed/2*(rand() % 3 - 1);
  204.          if(abs(ball.x-16000) > 10000 && ball.y > 10900) {one.speed_x = -one.speed_x;one.speed_y = -one.speed_y;}
  205.       }
  206.       switch(two.device)
  207.       {
  208.          case 0 :
  209.             two.speed_x+=(mouse_x-100)*(game_speed/fps)*8*show_const;
  210.             two.speed_y+=(mouse_y-100)*(game_speed/fps)*8*show_const;
  211.             if(two.speed_x > human_speed) two.speed_x = human_speed;
  212.             else if(two.speed_x < -human_speed) two.speed_x = -human_speed;
  213.             if(two.speed_y > human_speed) two.speed_y = human_speed;
  214.             else if(two.speed_y < -human_speed) two.speed_y = -human_speed;
  215.             break;
  216.          case 1 :
  217.             if(key[KEY_UP])    two.speed_y = -human_speed;
  218.             if(key[KEY_DOWN])  two.speed_y = human_speed;
  219.             if(key[KEY_RIGHT]) two.speed_x = human_speed;
  220.             if(key[KEY_LEFT])  two.speed_x = -human_speed;
  221.             break;
  222.          case 2 : 
  223.             if(key[KEY_W]) two.speed_y = -human_speed;
  224.             if(key[KEY_X] || key[KEY_S]) two.speed_y = human_speed;
  225.             if(key[KEY_D]) two.speed_x = human_speed;
  226.             if(key[KEY_A]) two.speed_x = -human_speed;
  227.             break;
  228.          case 3 :  computer_speed=150*fps;
  229.             break;
  230.          case 4 :  computer_speed=300*fps;
  231.             break;
  232.          case 5 :  computer_speed=450*fps;
  233.             break;
  234.          default : computer_speed=700*fps;
  235.       }
  236.       if(two.device > 2) {
  237.          if(two.x > ball.x && two.x > 9000) two.speed_x = -computer_speed;
  238.          if(two.x < ball.x && two.x < 22900) two.speed_x = computer_speed;
  239.          if(two.y < ball.y && ball.y < 10000) two.speed_y = computer_speed;
  240.          if(two.y > 3000 && (ball.y > 10000 || two.y > ball.y-1000)) two.speed_y = -computer_speed;
  241.          if(abs(two.x-ball.x) < 500 && ball.y > 10000) two.speed_x=computer_speed/2*(rand() % 3 - 1);
  242.          if(abs(ball.x-16000) > 10000 && ball.y < 9000) {two.speed_x = -two.speed_x;two.speed_y = -two.speed_y;}
  243.       }
  244.       if(!two.device || !one.device) position_mouse(100,100);
  245.       one.x+=one.speed_x; one.y+=one.speed_y;
  246.       two.x += two.speed_x; two.y += two.speed_y;
  247.       if(two.x < 9000) two.x = 9000; 
  248.       else if(two.x > 22900) two.x = 22900;
  249.       if(two.y < 3000) two.y = 3000;
  250.       else if(two.y > 9000) two.y = 9000;
  251.       if(one.x < 9000) one.x = 9000;
  252.       else if(one.x > 22900) one.x = 22900;
  253.       if(one.y < 11000) one.y = 11000;
  254.       else if(one.y > 16900) one.y = 16900;
  255.       ball_interaction(one.x,one.y,one.speed_x,one.speed_y);
  256.       ball_interaction(two.x,two.y,two.speed_x,two.speed_y);
  257.       if(too_close) too_close--;
  258.       if ( (one.x-ball.x)*(one.x-ball.x) + (one.y-ball.y)*(one.y-ball.y)
  259.       < 3600000 && too_close < 6) {
  260.          one.x = one.old_x;
  261.          one.y = one.old_y;
  262.          ball.x = ball.old_x;
  263.          ball.y = ball.old_y;
  264.          ball.speed_x *= 1.4;
  265.          ball.speed_y *= 1.4;
  266.          too_close += 2;
  267.       }
  268.       if ( (two.x-ball.x)*(two.x-ball.x) + (two.y-ball.y)*(two.y-ball.y) 
  269.       < 3600000 && too_close < 6) {
  270.          two.x = two.old_x;
  271.          two.y = two.old_y;
  272.          ball.x = ball.old_x;
  273.          ball.y = ball.old_y;
  274.          ball.speed_x *= 1.4;
  275.          ball.speed_y *= 1.4;
  276.          too_close += 2;
  277.       }
  278.       one.speed_x = 0; one.speed_y = 0; two.speed_x = 0; two.speed_y = 0;
  279.       if(!show_frame) {
  280.       show_frame=show_const;
  281.       if (key[KEY_F]) {                                             
  282.          sprintf(score_buf, "%d", (int)((game_speed/fps)/show_const));
  283.          draw_word(1,1,score_buf,205);
  284.       }
  285.       set_clip(active_page, 80, 20, 239, 179);
  286.       blit(page3, active_page, 0, 0, 80, 20, 160, 160); 
  287.       if(!smiley && game_time % 5 == 0 && boris != game_time) {
  288.           boris = game_time; 
  289.           draw_word((rand() % (160-strlen(message[word])*20)),
  290.           (rand() % 140), message[word], 201);
  291.           word++;
  292.           if(word > 103) {
  293.              smiley = 1;
  294.              draw_compiled_sprite(page3, datafile[BITMAP_007].dat, 0, 0);
  295.           }
  296.       }
  297.       if(!w) {
  298.          an_pos += an_dir; if (an_pos > 150) an_dir=-1; if (an_pos < 1) an_dir=1;
  299.          fps=(double)game_speed/((double)frame_count/game_time);
  300.          clear(one.progress); clear(two.progress);
  301.         if(!sb_mod_active) sb_mod_play(mod);
  302.          blit(datafile[BITMAP_004].dat, one.progress, an_pos, 0, 0, 0, 160-(11-score_max)*14, 15);
  303.          blit(datafile[BITMAP_004].dat, two.progress, 150-an_pos, 0, 0, 0, 160-(11-score_max)*14, 15);
  304.          drawing_mode(DRAW_MODE_COPY_PATTERN, datafile[BITMAP_003].dat, 150-an_pos, 0);
  305.          for (x=0; x<two.score; x++) {
  306.             circlefill(two.progress, (x*14) + 10, 7, 5, 1);
  307.          }
  308.          drawing_mode(DRAW_MODE_COPY_PATTERN, datafile[BITMAP_003].dat, an_pos, 0);
  309.          circlefill(one.bat, 10, 10, 10, 0);
  310.          for (x=0; x<one.score; x++) {
  311.             circlefill(one.progress, (x*14) + 10, 7, 5, 1);
  312.          }
  313.          solid_mode();
  314.          draw_sprite(one.progress, end1, 0, 0); draw_sprite(two.progress, end1, 0, 0);
  315.          floodfill(one.progress, 1, 1, 0);      floodfill(two.progress, 1, 1, 0);
  316.          floodfill(one.progress, 1, 14, 0);     floodfill(two.progress, 1, 14, 0);
  317.          eofscore = 14 * score_max + 5;
  318.          draw_sprite(one.progress, end2, eofscore-7, 0); draw_sprite(two.progress, end2, eofscore-7, 0);
  319.          floodfill(one.progress, eofscore, 1, 0);        floodfill(two.progress, eofscore, 1, 0);
  320.          floodfill(one.progress, eofscore, 14, 0);       floodfill(two.progress, eofscore, 14, 0);
  321.          drawing_mode(DRAW_MODE_COPY_PATTERN, ball.progress, an_pos, 0);
  322.          circlefill(ball.bat, 10, 10, 10, 0);
  323.          drawing_mode(DRAW_MODE_COPY_PATTERN, datafile[BITMAP_003].dat, 299-an_pos, 0);
  324.          circlefill(two.bat, 10, 10, 10, 0);
  325.          solid_mode();
  326.          w=(game_speed/fps)/5;
  327.       }
  328.       draw_sprite(active_page, two.bat, (two.x/100)-10, (two.y/100)-10);
  329.       if(!exit_loop) draw_sprite(active_page, ball.bat, (ball.x/100)-10, (ball.y/100)-10);
  330.       draw_sprite(active_page, one.bat, (one.x/100)-10, (one.y/100)-10);
  331.       one.old_x = one.x; two.old_x = two.x; one.old_y = one.y; two.old_y = two.y;
  332.       ball.old_x = ball.x; ball.old_y = ball.y;
  333.       set_clip(active_page, 0 , 0, 319, 199);
  334.       draw_sprite(active_page, one.progress, 80+(11-score_max)*7, 183);
  335.       draw_sprite(active_page, two.progress, 80+(11-score_max)*7, 2);
  336.       drawing_mode(DRAW_MODE_COPY_PATTERN, datafile[BITMAP_003].dat, 0+an_pos, 0);
  337.       circlefill(active_page, 160-goal_dist, 180, 3, 1);
  338.       circlefill(active_page, 160+goal_dist, 180, 3, 1);
  339.       drawing_mode(DRAW_MODE_COPY_PATTERN, datafile[BITMAP_003].dat, 150-an_pos, 0);
  340.       circlefill(active_page, 160-goal_dist, 20, 3, 1);
  341.       circlefill(active_page, 160+goal_dist, 20, 3, 1);
  342.       solid_mode();
  343.       page_flip();
  344.       }
  345.    }
  346.    rectfill(active_page, 0, 0, 319, 19, 0);
  347.    rectfill(active_page, 0, 180, 319, 199, 0);
  348.    draw_word(70,2,"game over",0);
  349.    if(exit_loop == 1) draw_word(40,182,"player 1 win",0);
  350.    else if(exit_loop == 2) draw_word(40,182,"player 2 win",0);
  351.    else draw_word(70,182,"game over",0);
  352.    page_flip();
  353.    rectfill(active_page, 0, 0, 319, 19, 0);
  354.    rectfill(active_page, 0, 180, 319, 199, 0);
  355.    draw_word(70,2,"game over",0);
  356.    if(exit_loop == 1) draw_word(40,182,"player 1 win",0);
  357.    else if(exit_loop == 2) draw_word(40,182,"player 2 win",0);
  358.    else draw_word(70,182,"game over",0);
  359.    page_flip();
  360.    frame_count /= (2.3 * show_const);
  361.    x=0;
  362.    while(x<(25/fps) && !key[KEY_SPACE] && !key[KEY_ENTER]) {
  363.       blit(screen, shrink, 80, 20, 0, 0, 160, 160);
  364.       redo=1; ball.speed_x=0; ball.speed_y=0; x++;
  365.       one.x = 16000; one.y = 16900; two.speed_x = 0; two.speed_y = 0;
  366.       two.x = 16000; two.y = 3000; one.speed_x = 0; one.speed_y = 0;
  367.       one.score=0; two.score=0; exit_loop = 0; w = 0;
  368.    }
  369.    intro();
  370.    goto restart;
  371. }
  372. ball_interaction(int bat_x, int bat_y, int bat_xspeed, int bat_yspeed)
  373. {
  374.    long temp;
  375.    double angle, incoming_angle, out_angle, new_velocity, ball_velocity,
  376.           bat_velocity, bat_angle, real_bat_velocity;
  377.    temp = ((bat_x+bat_xspeed-(ball.x+ball.speed_x))*(bat_x+bat_xspeed-(ball.x+ball.speed_x))
  378.    + (bat_y+bat_yspeed-(ball.y+ball.speed_y))*(bat_y+bat_yspeed-(ball.y+ball.speed_y))); 
  379.    if(temp < 4000000) {
  380.       angle = too_circle((ball.x-bat_x), (ball.y-bat_y));
  381.       incoming_angle = too_circle(ball.speed_x, ball.speed_y) - pi;
  382.       if(incoming_angle < 0) incoming_angle += 2 * pi;
  383.       if((ball.speed_x == 0 && ball.speed_y == 0) || just_hit) incoming_angle = angle;
  384.       if(!just_hit && sound_on) {
  385.          sample[0]->left_volume=36;
  386.          sample[0]->right_volume=36;
  387.          sb_mix_sample(sample[0]);
  388.       }
  389.       just_hit = 2;
  390.       out_angle = 2 * angle - incoming_angle;
  391.       if(fabs(incoming_angle-angle) > pi/2 && fabs(incoming_angle-angle) < 3*pi/2)
  392.          out_angle += pi;
  393.       if(out_angle > 2 * pi) out_angle -= 2 * pi;
  394.       else if(out_angle < 0) out_angle += 2 * pi;
  395.       if(fabs(angle-out_angle) > pi/2 && fabs(angle-out_angle) < 3*pi/2)
  396.          out_angle += pi;
  397.       if(out_angle > 2 * pi) out_angle -= 2 * pi;
  398.       ball_velocity=(double)(ball.speed_x*ball.speed_x+ball.speed_y*ball.speed_y);
  399.       bat_velocity= (double)(bat_xspeed*bat_xspeed+bat_yspeed*bat_yspeed);
  400.       bat_angle = too_circle(bat_xspeed, bat_yspeed);
  401.       real_bat_velocity = sqrt(bat_velocity) * cos(out_angle - bat_angle);
  402.       new_velocity=( sqrt(ball_velocity) * 0.7 + real_bat_velocity * 1.4 );
  403.       ball.speed_x = fabs(new_velocity * sin(out_angle));
  404.       ball.speed_y = fabs(new_velocity * cos(out_angle));
  405.       if(out_angle >= 0 && out_angle < pi / 2) ball.speed_y *= -1;
  406.       else if(out_angle >= pi && out_angle < 3 * pi / 2)  ball.speed_x *= -1;
  407.       else if(out_angle >= 3 * pi / 2 && out_angle < 2 * pi) {
  408.          ball.speed_y *= -1; ball.speed_x *= -1;
  409.       }
  410.       if(((bat_x-(ball.x+ball.speed_x))*(bat_x-(ball.x+ball.speed_x)) +
  411.       (bat_y-(ball.y+ball.speed_y))*(bat_y-(ball.y+ball.speed_y))) < temp) {
  412.          bat_xspeed *= -1; bat_yspeed *= -1;
  413.       }
  414.       if(debug) {
  415.          sprintf(score_buf, "A: %d IA %d OA %d BA %d T %d\n", (int)(angle*180/pi),
  416.          (int)(incoming_angle*180/pi), (int)bat_angle*180/pi, (int)(out_angle*180/pi),
  417.          frame_count);
  418.          fputs(score_buf, fp);
  419.       }
  420.    }
  421. }
  422. page_flip()
  423. {      
  424.    if (active_page == page1) {
  425.       scroll_screen(0, 0);
  426.       if(!t) {t=1;fade_in_range(datafile[PALLETE_001].dat, 2, 0, 255);}
  427.       active_page = page2;
  428.    }
  429.    else {
  430.       scroll_screen(0, SCREEN_H);
  431.       active_page = page1;
  432.    }
  433. }
  434. init()
  435. {
  436.    int x, y; char c;
  437.    printf("Shuffle v 1.1 by Michael Bevin - feel free to distribute\n");
  438.    allegro_init();
  439.    install_timer();
  440.    install_mouse();
  441.    install_keyboard();
  442.    set_gfx_mode(GFX_MODEX, 320, 200, 0, 720);
  443.    set_mouse_speed(2, 2);
  444.    position_mouse(100,100);
  445.    datafile = load_datafile("shuffle.dat");
  446.    if (!datafile) {
  447.       allegro_exit();
  448.       printf("Error loading shuffle.dat!\n\n");
  449.       exit(1);
  450.    }
  451.    set_pallete(black_pallete);
  452.    if(sound_on) {
  453.       if(sb_install_driver(11000)!=SB_SUCCESS) sound_on = 0;
  454.       else {
  455.          sample[0]=sb_load_sample("hit.wav",_SB_WAV);
  456.          sample[1]=sb_load_sample("cheer.wav",_SB_WAV);
  457.          mod=sb_load_mod_file("tune.mod");
  458.          if(mod==NULL || sample[0]==NULL || sample[1]==NULL) {
  459.             allegro_exit();
  460.             printf("Error initialising sound system\n");
  461.             sb_uninstall_driver();
  462.             exit(1);
  463.          }
  464.          sb_mod_play(mod);
  465.       }
  466.    }
  467.    page1 = create_sub_bitmap(screen, 0, 0, SCREEN_W, SCREEN_H);
  468.    page2 = create_sub_bitmap(screen, 0, SCREEN_H, SCREEN_W, SCREEN_H);
  469.    page3 = create_sub_bitmap(screen, 0, SCREEN_H*2, SCREEN_W, SCREEN_H);
  470.    one.bat =  create_bitmap(24,24);      clear(one.bat);
  471.    two.bat =  create_bitmap(24,24);      clear(two.bat);
  472.    ball.bat = create_bitmap(24,24);      clear(ball.bat);
  473.    two.progress = create_bitmap(160,15); clear(two.progress);
  474.    one.progress = create_bitmap(160,15); clear(one.progress);
  475.    shrink = create_bitmap(160,160);      clear(shrink);
  476.    rotate = create_bitmap(200,200);      clear(rotate);
  477.    ball.progress = create_bitmap(320,64);
  478.    circlefill(one.bat, 12, 13, 10, 4);
  479.    circlefill(two.bat, 12, 13, 10, 4);
  480.    circlefill(ball.bat, 12, 13, 10, 4);
  481.    blit(datafile[BITMAP_003].dat, ball.progress, 0, 0, 0, 0, 320, 64);
  482.    for(x=0;x<320;x++) {
  483.       for(y=0; y<25;y++)
  484.          ball.progress->line[y][x] = 255 - ball.progress->line[y][x];
  485.    }
  486.    end1 = create_bitmap(8,15); clear_to_color(end1, 255);
  487.    end2 = create_bitmap(8,15); clear_to_color(end2, 255);
  488.    circlefill(end1, 7, 7, 7, 0);
  489.    circlefill(end2, 0, 7, 7, 0);
  490.    active_page = page2; ball.speed_x=0;
  491.    ball.speed_y=0; one.device=0; two.device=3;
  492.    one.old_x = 16000; one.old_y = 16900; two.old_x = 16000; two.old_y = 3000;
  493.    one.x = 16000;     one.y = 16900;     two.x = 16000;     two.y = 3000;               
  494.    one.speed_x = 0;   one.speed_y = 0;   two.speed_x = 0;   two.speed_y = 0; 
  495.    one.score = 0;     two.score = 0;
  496.    draw_compiled_sprite(page1, datafile[BITMAP_001].dat, 0, 0);
  497.    draw_compiled_sprite(page2, datafile[BITMAP_001].dat, 0, 0);
  498. }
  499. intro()
  500. {
  501.    int x = 0; int an_pos, w, an_dir, smileypos; int r = 0;
  502.    char max_buf[3];
  503.    an_pos=0; w=1; an_dir=1; smileypos=0;
  504.    clear_keybuf();
  505.    draw_compiled_sprite(page3, datafile[BITMAP_001].dat, 0, 0);
  506.    while(r != KEY_SPACE && r != KEY_ENTER) {
  507.       w--; if(w<0) w=0;
  508.       x += 20/(game_speed/fps) + 1;
  509.       if(!w) {
  510.          an_pos += an_dir;
  511.          w=(game_speed/fps)/3;
  512.          if (an_pos > 150) an_dir = -1;
  513.          if (an_pos < 2) an_dir = 1;
  514.       }
  515.       blit(page3, active_page, 0, 0, 0, 0, 320, 200); 
  516.       if(redo && x<160) {
  517.          clear(rotate);
  518.          stretch_blit(shrink, rotate, 0, 0, 160, 160, x/2 + 20, x/2 + 20, 160-x, 160-x);
  519.          rotate_sprite(active_page, rotate, 60, 0, itofix(x*2));
  520.       }
  521.       rectfill(active_page, 0, 0, 319, 19, 0);
  522.       rectfill(active_page, 0, 180, 319, 199, 0);
  523.       rectfill(active_page, 92, 52, 232, 57, 1);
  524.       draw_word(90, 30, "shuffle", an_pos);
  525.       drawing_mode(DRAW_MODE_COPY_PATTERN, datafile[BITMAP_003].dat, an_pos, 0);
  526.       rectfill(active_page, 90, 50, 230, 55, 255);
  527.       solid_mode();
  528.       draw_word(60, 90+smileypos*20, ":", 0);
  529.       if(keypressed()) {
  530.          r = readkey() >> 8;
  531.          if(r == KEY_ESC) {
  532.            sb_uninstall_driver();
  533.            sb_free_sample(sample[0]);
  534.            sb_free_sample(sample[1]);
  535.            sb_free_mod_file(mod);
  536.            unload_datafile(datafile);
  537.            if(debug) fclose(fp);
  538.            exit(0);
  539.          }
  540.          if(r == KEY_DOWN) {smileypos++; if(smileypos > 3) smileypos = 0;}
  541.          if(r == KEY_UP) {smileypos--; if(smileypos < 0) smileypos = 3;}
  542.          else if(r == KEY_RIGHT) {
  543.             if(!smileypos) {one.device++; if(one.device>6) one.device=0;}
  544.             else if(smileypos == 1) {two.device++;if(two.device>6) two.device=0;}
  545.             else if(smileypos == 2) {score_max++;if(score_max>11) score_max = 1;}
  546.             else {goal_dist++;if(goal_dist>80) goal_dist = 80;}
  547.          }
  548.          else if(r == KEY_LEFT) {
  549.             if(!smileypos) {one.device--; if(one.device<0) one.device=6;}
  550.             else if(smileypos == 1) {two.device--;if(two.device<0) two.device=6;}
  551.             else if(smileypos == 2) {score_max--;if(score_max<1) score_max = 11;}
  552.             else {goal_dist--;if(goal_dist<30) goal_dist = 30;}
  553.          }
  554.          clear_keybuf();
  555.       }
  556.       switch(one.device) {
  557.          case 0 :  draw_word(80, 90, "1;mouse", 0);     break;
  558.          case 1 :  draw_word(80, 90, "1;keypad", 0);    break;
  559.          case 2 :  draw_word(80, 90, "1;keyboard", 0);  break;
  560.          case 3 :  draw_word(80, 90, "1;kiddie", 0);    break;
  561.          case 4 :  draw_word(80, 90, "1;easy", 0);      break;
  562.          case 5 :  draw_word(80, 90, "1;medium", 0);    break;
  563.          default : draw_word(80, 90, "1;hard", 0);
  564.       }
  565.       switch(two.device) {
  566.          case 0 :  draw_word(80, 110, "2;mouse", 0);     break;
  567.          case 1 :  draw_word(80, 110, "2;keypad", 0);    break;
  568.          case 2 :  draw_word(80, 110, "2;keyboard", 0);  break;
  569.          case 3 :  draw_word(80, 110, "2;kiddie", 0);    break;
  570.          case 4 :  draw_word(80, 110, "2;easy", 0);      break;
  571.          case 5 :  draw_word(80, 110, "2;medium", 0);    break;
  572.          default : draw_word(80, 110, "2;hard", 0);
  573.       }
  574.       clear(one.progress);
  575.       blit(datafile[BITMAP_004].dat, one.progress, an_pos, 0, 0, 0, 160-(11-score_max)*14, 15);
  576.       draw_sprite(one.progress, end1, 0, 0);
  577.       floodfill(one.progress, 1, 1, 0);     
  578.       floodfill(one.progress, 1, 14, 0);    
  579.       draw_sprite(one.progress, end2, 14 * score_max - 2, 0);
  580.       floodfill(one.progress, 14 * score_max + 5, 1, 0);      
  581.       floodfill(one.progress, 14 * score_max + 5, 14, 0);     
  582.       draw_sprite(active_page, one.progress, 80, 130);
  583.       drawing_mode(DRAW_MODE_COPY_PATTERN, datafile[BITMAP_004].dat, an_pos, 0);
  584.       line(active_page, 80, 158, 240, 158, 0);
  585.       drawing_mode(DRAW_MODE_COPY_PATTERN, datafile[BITMAP_003].dat, 150-an_pos, 0);
  586.       circlefill(active_page, 160-goal_dist, 158, 3, 1);
  587.       circlefill(active_page, 160+goal_dist, 158, 3, 1);
  588.       solid_mode();
  589.       page_flip();
  590.       frame_count++;
  591.       fps=(double)game_speed/(frame_count/game_time)*2;
  592.    }
  593.    draw_compiled_sprite(page1, datafile[BITMAP_001].dat, 0, 0);
  594.    draw_compiled_sprite(page2, datafile[BITMAP_001].dat, 0, 0);
  595.    srand(an_pos);
  596. }
  597. draw_word(int xx, int yy, char *cc, int col)
  598. {
  599.    BITMAP *letter, *temp;
  600.    int v, w, y, z; char ccc, d;
  601.    z = strlen(cc);
  602.    if(col && col<200) {
  603.       letter = create_bitmap(z*20+2, 18);
  604.       temp = create_bitmap(z*20,16);
  605.       clear(temp);
  606.    }
  607.    else letter = create_bitmap(z*20,16);
  608.    clear(letter);
  609.    if(col==205) draw_compiled_sprite(active_page, datafile[BITMAP_001].dat, 0, 0);
  610.    for(w=0; w<z;w++) {
  611.       ccc = *cc++;
  612.       v = ccc - 97;                    
  613.       if(v>=0) y = 1;     
  614.          else {v += 49; y = 19;}
  615.       blit(datafile[BITMAP_005].dat, letter, v*17+1, y, w*20, 0, 16, 16);
  616.    }
  617.    if(col && col<200) {
  618.       blit(letter, temp, 0, 0, 0, 0, z*20, 17);
  619.       for(v=0;v<16;v++) {
  620.          for(w=0;w<(z*20);w++) {
  621.             d = getpixel(datafile[BITMAP_003].dat, col+w, v);
  622.             if(getpixel(temp, w, v) > 13) {
  623.                letter->line[v+2][w+2] = 1;
  624.                letter->line[v][w] = d;
  625.             };
  626.          }
  627.       }
  628.    }
  629.    if(col==201) {
  630.       draw_compiled_sprite(page3, datafile[BITMAP_002].dat, 0, 0);
  631.       for(v=0;v<16;v++) {
  632.          for(w=0;w<(z*20);w++) {
  633.             d = getpixel(datafile[BITMAP_006].dat, w+xx, v+yy);
  634.             if(getpixel(letter, w, v) < 13) letter->line[v][w] = 0;
  635.             else letter->line[v][w] = d;
  636.          }
  637.       }
  638.       draw_sprite(page3, letter, xx, yy);
  639.    }
  640.    else draw_sprite(active_page, letter, xx, yy);
  641.    destroy_bitmap(letter);
  642. }
  643.